#ifndef __FLYWEIGHT__
#define __FLYWEIGHT__

#include <iostream>
#include <map>
#include <string>

typedef std::string STATE;
using namespace std;

class FlyWeight
{
	public:

		virtual ~FlyWeight() {}

		//操作外部状态使用，在本例子中没有用外部状态
		virtual void Operation(STATE& extrinsicState) = 0;

		STATE GetIntrinsicState()
		{
			return a_state;
		}

	protected:
		FlyWeight(const STATE& state):a_state(state) {}

	private:
		STATE a_state;
};


class ConcreteFlyWeight: public FlyWeight
{
	public:
		ConcreteFlyWeight(const STATE& state):FlyWeight(state) {}

		virtual ~ConcreteFlyWeight() {};
		
		virtual void Operation(STATE& extrinsicState)
		{
			cout << "concreteFlyWeight--"<< extrinsicState << endl;
			return;
		}
};

class FlyWeightFactory
{
	private:
		map<string, FlyWeight*> flyWeightMap;

	public:
		FlyWeightFactory() {}

		~FlyWeightFactory()
		{
			map<string, FlyWeight*>::iterator it = flyWeightMap.begin();
			map<string, FlyWeight*>::iterator it_end = flyWeightMap.end();

			for (; it != it_end; ++it)
			{
				delete ((*it).second);
			}

			flyWeightMap.clear();
		}

		FlyWeight* getFlyWeight(const STATE& key)	
		{
			map<string, FlyWeight*>::iterator it = flyWeightMap.find(key);
			if (it != flyWeightMap.end())
			{
				cout << "flyweight, key=" << key << " has already exits"<< endl;
				return (*it).second;
			}
			else
			{
				FlyWeight* p_flyWeight = new ConcreteFlyWeight(key);
				flyWeightMap.insert(map<string, FlyWeight*>::value_type(key, p_flyWeight));
				cout << "creating new flyweight, key=" << key << endl;
				return p_flyWeight;
			}
		}


};

#endif
